Skip to content

Win artifact pr fixes v2#7

Merged
bashrusakh merged 50 commits into
mainfrom
win-artifact-pr-fixes-v2
Jun 26, 2026
Merged

Win artifact pr fixes v2#7
bashrusakh merged 50 commits into
mainfrom
win-artifact-pr-fixes-v2

Conversation

@bashrusakh

@bashrusakh bashrusakh commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added a visible connection status indicator in the header with detailed connection and health states.
    • Added new chat follow-up behavior options, including queue, steer, and send immediately.
    • Added a setting to strip a leading slash before sending text as a normal message.
  • Bug Fixes

    • Improved message sending behavior for queued and follow-up replies.
    • Updated model selection and provider actions to behave more consistently with current filters and user choices.
    • Refined session and worktree startup flow to wait for readiness more reliably.

Leonid Skorobogatyy added 30 commits June 23, 2026 23:23
Color the `↓<behind>` and `↑<ahead>` tokens on the right sidebar
Git sync button using `status-warning` and `status-info` theme
tokens, matching the existing UpstreamStatusPill pattern, so the
counts are immediately visible against the muted label.
Fix openchamber#1440: Tab key was bound to cycle_agent by default, switching agents
when no autocomplete was open. Changed defaultCombo to empty string so
users must configure it. Model picker's own Tab handling is unaffected.
Fix openchamber#1462: handleDisconnectProvider called the SDK auth.remove() which
only clears auth credentials from auth.json. Cloud providers configured
in user/project/custom config files were not removed and reappeared
after reload. Now calls DELETE /api/provider/:id/auth?scope=all which
removes the provider from all config sources.
Fix openchamber#1527: agent picker filtered by mode !== 'subagent' which missed
agents with unexpected mode values. Now uses isPrimaryMode() which
only includes 'primary', 'all', undefined, and null — the semantically
correct set of agents that should appear in the picker.
Updated AgentSelector.tsx to use isPrimaryMode instead of mode !== 'subagent'.
Removed duplicate isPrimaryMode definition from useConfigStore.ts and
imported the shared helper from mobileControlsUtils.
Fix openchamber#1530: archive sub-session layout broken because the virtualizer
used a fixed 28px height estimate per row. Expanded parents with inline
children are much taller. Now dynamically increases bufferSize when
expanded parents are present.
The expansion key was using raw sessionId instead of the scoped format
'project:{archived|active}:{sessionId}'. This made hasExpandedParent
always false, so bufferSize never increased. Also removed dead
hasSessionSearchQuery branch.
…on list

Added sessions.length === 0 guard to useSidebarPersistence.ts and
sessions.length === 0 && archivedSessions.length === 0 guard to
useSessionFolderCleanup.ts. Prevents data loss when server returns
empty list during transient failures.
Fix openchamber#1662: switching the agent in the chat picker did not update the
provider/model in the UI. Two restore effects (restore from last user
message, restore from session selections) were firing after setAgent
and reverting the switch via their own setAgent calls.

Both effects now check explicitAgentSwitchRef.current === currentAgentName
and short-circuit. The ref is set in handleAgentChange (line 1176) and
cleared in the agent-switch effect (line 1026), so the guard is only
active for the single commit cycle where the explicit switch needs to
win.

Additionally, setAgent in useConfigStore now passes the agent's pinned
variant (validated against agentModel.variants) instead of undefined.
Previously the agent's variant was silently dropped on every agent
switch, even when one was configured.
Fix openchamber#1685: the Basic auth header for the OpenCode server was hardcoded
to use the username 'opencode', ignoring OPENCODE_SERVER_USERNAME. Users
who set a custom username got 401 errors because the server expected a
different credential.

Both call sites (web server auth-state-runtime.js and VS Code
extension opencode.ts) now read process.env.OPENCODE_SERVER_USERNAME
with a fallback to 'opencode' to preserve prior behavior.
Fix openchamber#1691: clicking 'Hide all' or 'Show all' in the providers page
previously acted on the full provider model list, ignoring the active
modelQuery search filter.

Both buttons now operate on filteredModels instead of providerModels.
The showAllModels store action gains an optional modelIDs parameter
(backwards compatible: when omitted, the prior behavior of un-hiding
all models for the provider is preserved).
Fix openchamber#1521: openNewSessionDraft() always used currentDirectory even when
the user selected a different project. Now prefers the selected project's
path when no explicit directory is provided.
Fix openchamber#1551: unshareSession() called updateLiveSession() which silently
fails when the child store doesn't exist. The sidebar rendered from the
child store first, showing stale share data. Now overlays the global
session's share field at merge points.
Extracted the share-field overlay into a single shared helper in
useGlobalSessionsStore.ts. All 3 merge sites now use the helper
instead of duplicating the overlay logic.
Fix openchamber#1636: ToolPart.tsx reset pinnedTime to empty on unmount/remount,
causing LiveDuration to not render on first paint. Now initializes
pinnedTime from server-provided time?.start/time?.end in the useState
initializer, eliminating the one-frame gap.
…are reflected

The load logic in BehaviorPage treated globalBehaviorPrompt from
settings.json as the primary source and AGENTS.md as a fallback. Since
every save writes globalBehaviorPrompt back to settings.json, this field
was always present after the first save — making the AGENTS.md fallback
dead code. External edits to AGENTS.md were invisible in the UI, and
clicking Save would overwrite the real file with the stale cached copy.

Swap the priority: read AGENTS.md first (the actual source of truth used
by OpenCode at runtime), and only fall back to globalBehaviorPrompt when
the file is missing or empty.
When clearing temperature or topP on an existing agent, the UI sent
undefined which JSON.stringify drops, so the server never received the
clear command. Now sends null to properly remove the override in
opencode.json.

Changed updateAgent to use 'field' in config pattern for temperature
and top_p, matching the existing prompt handling.
Fix openchamber#1425: add variant field to agent config UI so users can configure
thinking/reasoning depth per agent without editing opencode.json.

Changes:
- Added variant to AgentConfig and AgentDraft types in useAgentsStore
- Pass variant in createAgent and updateAgent API calls
- Support null for temperature, top_p, and variant to clear overrides
- Added variant input field in AgentsPage 'Model & Parameters' section
- Added variant to settings search registry
- Added i18n strings for variant field in all 8 non-English locales

The variant field maps to provider-specific parameters (e.g. Anthropic
high/max variant, OpenAI reasoning effort). Users can enter any string
value; the SDK passes it through to the model provider.

Clearing temperature/topP/variant now sends null to the server instead
of omitting the field, which properly removes the override in
opencode.json.
Replace mutable version tags with SHA-pinned references matching the
convention used across .github/workflows/*.yml.
Leonid Skorobogatyy and others added 19 commits June 24, 2026 00:08
…penchamber#1556)

- Hop-separated narrow state in useConfigStore (runtimeTransport,
  openCodeRuntime) driven by the existing SSE/WS reconnect pipeline
  and the existing opencodeClient.checkHealth() path. No new
  polling loop.
- Pure helper packages/ui/src/lib/connection-status/connectionStatus.ts
  that maps per-hop internal state + navigator.onLine to a single
  aggregated view model (connected / reconnecting / degraded /
  disconnected / unknown) and short i18n keys. Raw internal reason
  codes are kept in the view model for diagnostics only and never
  reach the UI.
- Compact header indicator packages/ui/src/components/layout/
  ConnectionStatusIndicator.tsx (one dot + hover tooltip with 2-3
  short lines, theme tokens only, React.memo on both layers,
  narrow leaf selectors). Wired into Header.tsx in the existing
  desktopSidebarActions cluster.
- 19 new connectionStatus.* i18n keys in all 9 dictionaries.
- 22 unit tests for the mapper covering all Phase 5 scenarios.
- One-line pre-existing fr.ts parity fix
  (sessions.scheduledTasks.editor.scheduleType.cron) so the i18n
  parity test passes; flagged in the PR body.

Validation: type-check + lint green in packages/ui, packages/web,
packages/electron. docs:validate green. 22 + 12 + 2 new/updated
tests pass. 5 pre-existing sync-pipeline test failures verified
unrelated to this diff.
Adds a 'Strip Slash on Submit' toggle in Settings > Chat. When enabled,
submitting a slash command or skill strips the leading slash and sends the
text as a plain message, so the conversation shows what the user typed
instead of the expanded skill prompt.

- Slash completion (/ dropdown) still works regardless of the setting
- Setting is persisted across reloads and synced across web/desktop/VS Code
- Default is off (current behavior preserved)
- ChatInput: gate the strip-slash branch on inputMode === 'normal' so
  shell-mode paths like /usr/bin/foo keep their leading slash, and align
  the regex with the routeMessage site (/^\/+/ anchored)
- session-ui-store: routeMessage now sends the stripped content to
  opencodeClient.sendMessage, not params.content, so multi-run and other
  callers do not show optimistic-insert vs server-text divergence
- Document that ChatInput owns the client-side built-in slash block
  while routeMessage owns the server-side sendCommand expansion
- Add stripSlashOnSubmit to SettingsPayload type in lib/api/types.ts for
  documentation parity with inputSpellcheckEnabled
- Add the 3 new i18n keys to the 7 non-English locale files (es, fr, ko,
  pl, pt-BR, uk, zh-CN, zh-TW) so type-check no longer flags them as
  missing-key regressions
- Shorten the ariaLabel to the visible label; the visible description
  below covers the long-form copy
The regex /^\/+/ is anchored to column 0, so when primaryText has
leading whitespace (e.g. '  /help'), the condition matches via
trimStart() but the replacement is a no-op leaving the slash intact.
Use /^(\s*)\/+/ with  capture to preserve whitespace while
stripping leading slashes.

Found by open-code-review (ocr).
Signed-off-by: bashrusakh <127580858+bashrusakh@users.noreply.github.com>
Signed-off-by: bashrusakh <127580858+bashrusakh@users.noreply.github.com>
Implements issue openchamber#1766 — steer delivery mode for mid-turn message
insertion, replacing the old boolean queue-mode toggle with a tri-state
follow-up behavior setting (Steer / Queue / Send immediately).

- Plumbing: threaded optional delivery: 'steer' through sendMessage
  -> routeMessage -> opencodeClient.sendMessage -> promptAsync
- Store: messageQueueStore stores followUpBehavior; migration from
  legacy queueModeEnabled persisted state
- Settings: Chat -> Follow-up behavior shows three radio options
  using existing settings UI patterns
- Composer: when session is busy, a floating queue button remains;
  force-sending a queued message (via chip click) uses delivery: 'steer'
  during a busy session; Steer button intentionally omitted — steer is
  available via the two-gesture path (Enter to queue -> chip to steer)
- Keyboard: queue mode = Enter queues, Ctrl+Enter sends; otherwise
  Enter sends, Ctrl+Enter queues
- Persistence: DesktopSettings, web settings payload, and server-side
  sanitizer handle the new key with legacy fallback
- i18n: follow-up behavior section and option labels in all 9 locales
  plus new chat.chatInput.actions.queue label
- Search: settings registry updated from chat.queue-mode to
  chat.follow-up-behavior

Validation: type-check passes (no new errors), lint clean.
The followUpBehavior === 'steer' branch in handlePrimaryAction and the
keyboard handler was a no-op — both fell into the else branch and sent
without the delivery: 'steer' flag, so selecting 'Steer (insert into
the running turn)' in settings produced identical behavior to 'Send
immediately'.

- handlePrimaryAction: when steer mode is selected and the session is
  busy, call handleSubmit({ delivery: 'steer' }) directly
- Keyboard handler: in steer mode, Enter steers and Ctrl+Enter sends
  immediately (consistent with queue mode where Ctrl+Enter bypasses
  the special handling)

Also removes the unused chat.chatInput.actions.queue i18n key from all
9 locales (it was a dead key after the Steer button was removed from
the composer).

Validation: type-check clean, lint clean.
…r resolution

Replace nested ternary with explicit if/else chain per project code style
(CONTRIBUTING.md). Import FollowUpBehavior type explicitly for the new
let declaration.
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a8d55d2b-7b2f-4b33-88b1-4a64d9774892

📥 Commits

Reviewing files that changed from the base of the PR and between 42ecc99 and f903175.

📒 Files selected for processing (29)
  • .github/workflows/pr-review.yml
  • packages/ui/src/components/chat/ChatInput.tsx
  • packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx
  • packages/ui/src/lib/api/types.ts
  • packages/ui/src/lib/desktop.ts
  • packages/ui/src/lib/i18n/messages/en.settings.ts
  • packages/ui/src/lib/i18n/messages/en.ts
  • packages/ui/src/lib/i18n/messages/es.settings.ts
  • packages/ui/src/lib/i18n/messages/es.ts
  • packages/ui/src/lib/i18n/messages/fr.settings.ts
  • packages/ui/src/lib/i18n/messages/fr.ts
  • packages/ui/src/lib/i18n/messages/ko.settings.ts
  • packages/ui/src/lib/i18n/messages/ko.ts
  • packages/ui/src/lib/i18n/messages/pl.settings.ts
  • packages/ui/src/lib/i18n/messages/pl.ts
  • packages/ui/src/lib/i18n/messages/pt-BR.settings.ts
  • packages/ui/src/lib/i18n/messages/pt-BR.ts
  • packages/ui/src/lib/i18n/messages/uk.settings.ts
  • packages/ui/src/lib/i18n/messages/uk.ts
  • packages/ui/src/lib/i18n/messages/zh-CN.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-CN.ts
  • packages/ui/src/lib/i18n/messages/zh-TW.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-TW.ts
  • packages/ui/src/lib/opencode/client.ts
  • packages/ui/src/lib/persistence.ts
  • packages/ui/src/lib/settings/search.ts
  • packages/ui/src/lib/shortcuts.ts
  • packages/ui/src/lib/worktreeSessionCreator.ts
  • packages/ui/src/stores/useMultiRunStore.test.ts

📝 Walkthrough

Walkthrough

The PR updates workflow triggers and ignore rules, adds connection-status state and header display, replaces queue mode with follow-up behavior and slash stripping, changes provider and worktree flows, and adds related localization and documentation updates.

Changes

Repository automation

Layer / File(s) Summary
Workflow triggers and ignore rule
.github/workflows/pr-review.yml, .gitignore
Removes explicit webhook action filters from pr-review and adds .graymatter/ to .gitignore.

Sidebar performance plan

Layer / File(s) Summary
Performance plan
SIDEBAR_PERF_PLAN.md
Adds the Session Sidebar performance plan document.

Git sync label

Layer / File(s) Summary
Sync label
packages/ui/src/components/views/git/SyncActions.tsx
Renders ahead/behind counts as styled spans inside the sync button label.

Agent selection

Layer / File(s) Summary
Primary-mode filter and restore guard
packages/ui/src/components/chat/ModelControls.tsx, packages/ui/src/stores/useConfigStore.ts
Filters selectable desktop agents by primary mode and skips restore logic after explicit agent switches.
Cycle-agent shortcut
packages/ui/src/lib/shortcuts.ts
Removes the built-in default combo from cycle_agent.
Variant field translation
packages/ui/src/lib/i18n/messages/zh-CN.settings.ts
Adds the agents-page variant field label, tooltip, hint, and placeholder strings.

Connection status

Layer / File(s) Summary
Runtime state updates
packages/ui/src/stores/useConfigStore.ts, packages/ui/src/sync/sync-context.tsx, packages/ui/src/sync/__tests__/session-status-snapshot.test.ts
Adds runtime transport and OpenCode state fields, updates disconnect/offline handling, and tests terminal disconnect detection.
View model and tests
packages/ui/src/lib/connection-status/connectionStatus.ts, packages/ui/src/lib/connection-status/connectionStatus.test.ts
Adds the connection-status view model, reason classification, hop projection, tooltip line generation, and coverage for the aggregation rules.
Connection-status translations
packages/ui/src/lib/i18n/messages/en.ts, packages/ui/src/lib/i18n/messages/es.ts, packages/ui/src/lib/i18n/messages/fr.ts, packages/ui/src/lib/i18n/messages/ko.ts, packages/ui/src/lib/i18n/messages/pl.ts, packages/ui/src/lib/i18n/messages/pt-BR.ts, packages/ui/src/lib/i18n/messages/uk.ts, packages/ui/src/lib/i18n/messages/zh-CN.ts, packages/ui/src/lib/i18n/messages/zh-TW.ts
Adds localized connectionStatus.* strings and exports I18nKey from en.ts.
Indicator UI and header
packages/ui/src/components/layout/ConnectionStatusIndicator.tsx, packages/ui/src/components/layout/Header.tsx
Renders the connection-status indicator in the desktop header from narrow store selectors.

Follow-up behavior

Layer / File(s) Summary
Behavior state and persistence
packages/ui/src/stores/messageQueueStore.ts, packages/ui/src/stores/useUIStore.ts, packages/ui/src/lib/desktop.ts, packages/ui/src/lib/api/types.ts, packages/ui/src/lib/persistence.ts, packages/web/server/lib/opencode/settings-helpers.js
Replaces queue mode with followUpBehavior, adds stripSlashOnSubmit, and threads both settings through persistence and sanitization.
Chat submission and delivery
packages/ui/src/components/chat/ChatInput.tsx, packages/ui/src/sync/session-ui-store.ts, packages/ui/src/lib/opencode/client.ts
Routes submit handling through the new delivery option, strips leading slashes when enabled, and forwards steer delivery through sendMessage and routeMessage.
Settings UI and localization
packages/ui/src/components/sections/openchamber/OpenChamberPage.tsx, packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx, packages/ui/src/lib/settings/search.ts, packages/ui/src/lib/i18n/messages/*.settings.ts
Exposes the follow-up and strip-slash settings in OpenChamber, updates search entries, and adds localized labels and descriptions.

Provider management

Layer / File(s) Summary
Provider disconnect
packages/ui/src/components/sections/providers/ProvidersPage.tsx
Switches provider disconnect to the auth DELETE API and parses errors from the JSON response.
Filtered bulk model actions
packages/ui/src/components/sections/providers/ProvidersPage.tsx, packages/ui/src/stores/useUIStore.ts
Widen showAllModels to accept explicit ids and use filtered model ids when hiding or showing all models.

Behavior prompt

Layer / File(s) Summary
Prompt source
packages/ui/src/components/sections/behavior/BehaviorPage.tsx
Loads AGENTS.md content first and falls back to the persisted global behavior prompt when needed.

Worktree bootstrap

Layer / File(s) Summary
Bootstrap waits
packages/ui/src/lib/worktreeSessionCreator.ts, packages/ui/src/stores/useMultiRunStore.test.ts, packages/ui/src/sync/session-ui-store.ts
Adds worktree-bootstrap waits before session creation, a worktree-only creator, and ordering assertions in the multirun test.
Draft session materialization
packages/ui/src/sync/session-ui-store.ts, packages/ui/src/sync/session-ui-store.test.js
Moves draft-to-session creation into materializeOpenDraftSession, adjusts draft project/directory inference, and updates the draft-binding test.

Scheduled task translation

Layer / File(s) Summary
Cron translation
packages/ui/src/lib/i18n/messages/fr.ts
Adds the missing French cron schedule translation string.

Sequence Diagram(s)

sequenceDiagram
  participant ChatInput
  participant SessionUIStore
  participant OpencodeService
  participant OpenCodeSession
  ChatInput->>SessionUIStore: handleSubmit / routeMessage with followUpBehavior and stripSlashOnSubmit
  SessionUIStore->>OpencodeService: sendMessage(..., delivery)
  OpencodeService->>OpenCodeSession: promptAsync(...)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~90+ minutes

Possibly related PRs

  • bashrusakh/openchamber#5: Shares the connection-status state model and shouldUseDisconnectedTransportPhase flow used by SyncProvider and the header indicator.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the changeset because it references the Windows artifact work, which is one of the main areas touched.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch win-artifact-pr-fixes-v2

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

Signed-off-by: bashrusakh <127580858+bashrusakh@users.noreply.github.com>
@bashrusakh bashrusakh merged commit f84981d into main Jun 26, 2026
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant